// Copyright (C) 2022 即时通讯网(52im.net) & Jack Jiang.
// The RainbowChat Project. All rights reserved.
//
// 【本产品为著作权产品，合法授权后请放心使用，禁止外传！】
// 【本次授权给：<广西木子科技有限公司>，授权编号：<NT220402151538>，代码指纹：<A.648883738.885>，技术对接人微信：<ID: Lingmuziyi>】
// 【授权寄送：<收件：李先生、地址：南宁市科园西十路11号国电智能大厦1101F、电话：17736659550、邮箱：yingshashou@vip.qq.com>】
//
// 【本系列产品在国家版权局的著作权登记信息如下】：
// 1）国家版权局登记名(简称)和权证号：RainbowChat    （证书号：软著登字第1220494号、登记号：2016SR041877）
// 2）国家版权局登记名(简称)和权证号：RainbowChat-Web（证书号：软著登字第3743440号、登记号：2019SR0322683）
// 3）国家版权局登记名(简称)和权证号：RainbowAV      （证书号：软著登字第2262004号、登记号：2017SR676720）
// 4）国家版权局登记名(简称)和权证号：MobileIMSDK-Web（证书号：软著登字第2262073号、登记号：2017SR676789）
// 5）国家版权局登记名(简称)和权证号：MobileIMSDK    （证书号：软著登字第1220581号、登记号：2016SR041964）
// * 著作权所有人：江顺/苏州网际时代信息科技有限公司
//
// 【违法或违规使用投诉和举报方式】：
// 联系邮件：jack.jiang@52im.net
// 联系微信：hellojackjiang
// 联系QQ号：413980957
// 授权说明：http://www.52im.net/thread-1115-1-1.html
// 官方社区：http://www.52im.net
package com.x52im.rainbowchat.http.logic;

import java.util.Vector;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.eva.epc.common.util.CommonUtils;
import com.eva.framework.Processor;
import com.eva.framework.dbpool.DBDepend;
import com.eva.framework.dbpool.DBShell;
import com.eva.framework.dto.SysActionConst;
import com.eva.framework.utils.EndsExceptionFactory;
import com.eva.framework.utils.SNHelper;
import com.x52im.rainbowchat.http.logic.dto.GiftProcessResult;

/**
 * 礼品相关的Http接口处理器实现类。
 *
 * @author Jack Jiang
 * @since 4.3
 */
public class GiftProcessor2 implements SysActionConst, Processor {
    public static DBShell db = new DBShell();

    /**
     * 处理器的核心实现方法.<br>
     * 可据job_dispatch_id找到对应的JobDispatcher，JobDispatcher又能据
     * action_id进行对应动作的处理，以完成本次操作请求.
     *
     * @param job_dispatch_id 作业调度ID
     * @param action_id       动作ID
     * @param Object          newData 客端发送过来的本次修改新数据(可能为空，理论上与oldData不会同时空）
     * @param Object          oldData 客端发送过来的本次修改前的老数据(可能为空，理论上与newData不会同时空）
     * @param UserRoot        user 包含该请求用户完整个人信息封装对象（该对象来自于成功登陆后存放于session中的值）
     * @return 任意类型返回值
     * @throws Exception
     */
    @Override
    public Object process(int job_dispatch_id, int action_id, Object _newData, Object _oldData, User user)
            throws Exception {
        Object ret = null;
        String newDataJSON = (String) _newData;

        switch (job_dispatch_id) {
            // 处理礼品和积分相关
            case com.x52im.rainbowchat.http.logic.dto.JobDispatchConst.LOGIC_GIFTANDSCORE:
                ret = maintainGiftAndScoreJobDispatcher(action_id, newDataJSON, _oldData, user);
                break;

            default:
                throw EndsExceptionFactory.INVALID_JOB_DISPATCHER_ID(job_dispatch_id);
        }
        return ret;
    }

    /**
     * 维护礼品和积分相关管理.
     *
     * @param action_id 维护类型，SysConstant中的操作类型常量
     * @param newData   客端发送过来的本次修改新数据(可能为空，理论上与oldData不会同时空）
     * @param oldData   客端发送过来的本次修改前的老数据(可能为空，理论上与newData不会同时空）
     * @param userName  操作者的用户名
     * @return 返回给客户端的对象
     */
    public Object maintainGiftAndScoreJobDispatcher(int action_id, String newDataJSON, Object oldData, User user) throws Exception {
        Vector sqls = new Vector(2);
        Vector values = new Vector(2);

        switch (action_id) {
            // 【接口1012-21-7】查询用户的积分
            case ACTION_APPEND1: {
                // 要查询积分的用户uid
                JSONObject nwObj = JSONObject.parseObject(newDataJSON);
                String user_uid = nwObj.getString("user_uid");//(String)newData;
                return String.valueOf(queryScore(user_uid));
            }

            // 【接口1012-21-8】处理某人向另一人赠送礼品的数据
            case ACTION_APPEND2: {
                GiftProcessResult gpr = new GiftProcessResult();

//				String[] params = (String[])newData;
                JSONObject params = JSONObject.parseObject(newDataJSON);
                // 礼品赠送发起人
                String srcUid = params.getString("src_uid");//params[0];
                // 礼品接收人
                String destUid = params.getString("dest_uid");//params[1];
                // 礼品ident（即礼品的数据库主键id值）
                String giftIdent = params.getString("gift_ident");//params[2];

                //
                String giftPriceStr = LogicProcessor2.db
                        .querySingleItem("select price from missu_gifts where gift_ident='" + giftIdent + "'");
                // 没有查到该礼品的价格，就立即判定发送失效
                if (giftPriceStr == null) {
                    gpr.setResultCode(GiftProcessResult.RESULT_CODE_NO$PRICE);// 【返回值】没有查找指定礼品的价格
                    return JSON.toJSONString(gpr);
                }

                int giftPrice = CommonUtils.getIntValue(giftPriceStr);
                // 查询赠送发起人的当前积分
                int currentScore = queryScore(srcUid);
                // 把当前积分先保存到结果对像里以备返回给客户端哦
                gpr.setResultValue(String.valueOf(currentScore));
                if (giftPrice > currentScore) {
                    gpr.setResultCode(GiftProcessResult.RESULT_CODE_SCORE$NOT$ENOUGTH); // 【返回值】积分不足

                    return JSON.toJSONString(gpr);
                }

                try {
                    // 积分使用记录id
                    String missu_gifts_consume_id = SNHelper.getSN("missu_gifts_consume_id");
                    // ** 先插入一条“积分使用记录”
                    sqls.add("INSERT INTO missu_gifts_consume(" +
                            "consume_id,user_uid,mis_user_uid,gift_ident,amount,consume_time2,consume_time) " +
                            "VALUES(?,?,?,?,?,?," + DBDepend.getDefaultDatetimeFunc() + ")");
                    values.add(new Object[]{missu_gifts_consume_id, srcUid, destUid
                            , giftIdent, giftPrice, System.currentTimeMillis()});

                    // ** 再插入一条“我的礼品”记录
                    sqls.add("INSERT INTO missu_gifts_mine(user_uid,from_user_uid,get_time2" +
                            ",src_consume_id,gift_ident,get_time)" +
                            " VALUES(?,?,?,?,?," + DBDepend.getDefaultDatetimeFunc() + ")");
                    values.add(new Object[]{destUid, srcUid, System.currentTimeMillis()
                            , missu_gifts_consume_id, giftIdent});

                    // ** 减去发送者的积分
                    sqls.add("update token_user_token set current_token_count=current_token_count-? where user_uid=?");
                    values.add(new Object[]{giftPrice, srcUid});

                    // ** 提交数据库处理
                    LogicProcessor2.db.update(sqls, values, true);

                    // 返回值
                    gpr.setResultCode(GiftProcessResult.RESULT_CODE_OK); // 【返回值】处理成功！
//					return gpr;
                } catch (Exception e) {
                    // 返回值
                    gpr.setResultCode(GiftProcessResult.RESULT_CODE_OTHERERROR); // 【返回值】其它错误
//					return gpr;
                }

                return JSON.toJSONString(gpr);
            }

            // 【接口1012-21-9】用户所有礼品兑换成积分（将指定用户的礼品全部兑换成它对应的积分）
            case ACTION_APPEND3: {
                GiftProcessResult gpr = new GiftProcessResult();

                // 要兑换积分人的uid
                String srcUid = JSONObject.parseObject(newDataJSON).getString("src_uid");//(String)newData;
                if (srcUid != null) {
                    // 我的背包里的礼品
                    Vector<Vector> giftsToDuihuan = LogicProcessor2.db.queryData(
                            "select a.my_gift_rec_id,a.from_user_uid, a.get_time" +
                                    ", a.get_time2, a.gift_ident, b.price" +
                                    " from missu_gifts_mine a join missu_gifts b on a.gift_ident=b.gift_ident" +
                                    " where a.user_uid=" + srcUid);

                    if (giftsToDuihuan.size() > 0) {
                        // 本次要兑换礼品的总积分数
                        int toduanhuan_sum = 0;
                        // 本次兑换记录编号
                        String rec_id = SNHelper.getSN("missu_gifts_to_jifen_id");

                        // ** 【1】先插入一条“礼品兑换积分记录”
                        sqls.add("INSERT INTO missu_gifts_to_jifen(" +
                                "rec_id,user_uid,jifen_amount,charge_time2,charge_time) " +
                                "VALUES(?,?,?,?," + DBDepend.getDefaultDatetimeFunc() + ")");
                        values.add(new Object[]{rec_id, srcUid, "0", System.currentTimeMillis()});

                        // ** 【2】再插入一条“礼品兑换积分记录明细”
                        for (Vector r : giftsToDuihuan) {
                            int j = 0;
                            String toduihuan_my_gift_rec_id = (String) r.get(j++);
                            String toduihuan_from_user_uid = (String) r.get(j++);
                            String toduihuan_get_time = (String) r.get(j++);
                            String toduihuan_get_time2 = (String) r.get(j++);
                            String toduihuan_gift_ident = (String) r.get(j++);
                            String toduihuan_price = (String) r.get(j++);

                            // 总积分数+
                            toduanhuan_sum += CommonUtils.getIntValue(toduihuan_price);

                            // ** [1]插入一条“礼品兑换积分记录明细”
                            sqls.add("INSERT INTO missu_gifts_to_jifendetail(" +
                                    "rec_id,from_user_uid,gift_ident,jifen_amount, get_time, get_time2) VALUES(?,?,?,?,?,?)");
                            values.add(new Object[]{rec_id, toduihuan_from_user_uid
                                    , toduihuan_gift_ident, toduihuan_price, toduihuan_get_time, toduihuan_get_time2});

                            // ** [2]同时删除一条“我的礼品”，为了严谨（防止正在况换时又插了新礼品，此处是况换什么就先删除什么，与[1]一一对应）
                            sqls.add("DELETE FROM missu_gifts_mine where my_gift_rec_id=?");
                            values.add(new Object[]{toduihuan_my_gift_rec_id});
                        }

                        // ** 【3】更新“礼品兑换积分记录”中的“本次兑换的总积分数”
                        sqls.add("update missu_gifts_to_jifen set jifen_amount=jifen_amount+? where rec_id=?");
                        values.add(new Object[]{toduanhuan_sum, rec_id});

                        // ** 【4】新新兑换的总积分累加到该人员的总积分上去
                        // 该用户已存在积分记录
                        if (LogicProcessor2.db.queryData("select 1 from token_user_token where user_uid=" + srcUid).size() > 0) {
                            sqls.add("update token_user_token set current_token_count=current_token_count+? where user_uid=?");
                            values.add(new Object[]{toduanhuan_sum, srcUid});
                        }
                        // 该用户不存在积分记录，首先插入一条记录
                        else {
                            sqls.add("INSERT INTO token_user_token(user_uid, current_token_count) values(?,?)");
                            values.add(new Object[]{srcUid, toduanhuan_sum});
                        }

                        // ** 提交数据库处理
                        LogicProcessor2.db.update(sqls, values, true);

                        // 返回值
                        gpr.setResultCode(GiftProcessResult.RESULT_CODE_OK); // 【返回值】处理成功！
                    }
                }

                gpr.setResultValue(String.valueOf(queryScore(srcUid))); // 当前总积分数返回给客户端
                return JSON.toJSONString(gpr);
            }

            // 【接口1012-21-22】查询用户的礼品赠送记录
            case ACTION_APPEND4: {
                JSONObject nwObj = JSONObject.parseObject(newDataJSON);
                String localUid = nwObj.getString("local_uid");// 被查询用户的uid
                String gifIdent = nwObj.getString("gif_ident");// 礼品ident（即礼品的数据库主键id值）

                StringBuilder sb = new StringBuilder()
                        .append("select a.my_gift_rec_id,a.user_uid,a.from_user_uid,a.get_time ")
                        .append("	,a.get_time2,a.src_consume_id,a.gift_ident ")
                        .append("	,b.nickname,c.price,c.res_drawable_id ")
                        .append("from ")
                        .append("(")
                        .append("	select my_gift_rec_id,user_uid,from_user_uid,get_time,get_time2,src_consume_id,gift_ident ")
                        .append("	from missu_gifts_mine ")
                        .append("	where user_uid=" + localUid + " and gift_ident='" + gifIdent + "' ")
                        .append(") a ")
                        .append("left join missu_users b on a.from_user_uid=b.user_uid ")
                        .append("left join missu_gifts c on a.gift_ident=c.gift_ident ")
                        .append("order by a.get_time2 desc ");

                return JSON.toJSONString(db.queryData(sb.toString()));
            }

            // 【接口1012-21-23】查询用户的礼物列表
            case ACTION_APPEND5: {
                JSONObject nwObj = JSONObject.parseObject(newDataJSON);
                String localUid = nwObj.getString("local_uid");// 被查询用户的uid

                StringBuilder sb = new StringBuilder()
                        .append("select a.gift_ident,b.gift_name,b.price,b.res_drawable_id,a.quantity ")
                        .append("from ")
                        .append("(")
                        .append("	select gift_ident,count(*) as quantity ")
                        .append("		from missu_gifts_mine ")
                        .append("	where user_uid=" + localUid)
                        .append("	group by gift_ident ")
                        .append(") a ")
                        .append("join missu_gifts b on a.gift_ident=b.gift_ident order by b.price asc");

                return JSON.toJSONString(db.queryData(sb.toString()));
            }

            // 【接口1012-21-24】查询当前系统设定的礼物列表
            case ACTION_APPEND6: {
                return JSON.toJSONString(db.queryData("select gift_ident,gift_name,price,res_drawable_id,res_dialogue" +
                        " from missu_gifts where is_valid=1 order by price asc"));
            }


            default:
                throw EndsExceptionFactory.INVALID_ACTION_ID(action_id);
        }
    }

    private int queryScore(String uid) throws Exception {
        String sql = "select current_token_count from token_user_token where user_uid=" + uid; // 查询指定用户的积分
        String current_token_count = LogicProcessor2.db.querySingleItem(sql);
        if (current_token_count == null) // 没有查到该用户的积分记录
            return 0;
        else
            return CommonUtils.getIntValue(current_token_count);
    }
}
